package com.wayhome.srpingbootmybatis.mbs.expertimport.bo.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wayhome.srpingbootmybatis.config.ApiResult;
import com.wayhome.srpingbootmybatis.exception.CustomerException;
import com.wayhome.srpingbootmybatis.mbs.expertimport.bo.DipTldyManagerBO;
import com.wayhome.srpingbootmybatis.mbs.expertimport.dao.DipTldyInfoDAO;
import com.wayhome.srpingbootmybatis.mbs.expertimport.dao.SetlTldyExpertAuditMapper;
import com.wayhome.srpingbootmybatis.mbs.expertimport.dto.*;
import com.wayhome.srpingbootmybatis.mbs.expertimport.enums.DeptMajorEnum;
import com.wayhome.srpingbootmybatis.mbs.util.ApplyExitReaEnum;
import com.wayhome.srpingbootmybatis.mbs.util.HeadContentCellStyle;
import com.wayhome.srpingbootmybatis.mbs.util.TldyAuditEmum;
import com.wayhome.srpingbootmybatis.mbs.util.TldyStepEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DipTldyManagerBOImpl implements DipTldyManagerBO {

    @Resource
    DipTldyInfoDAO dipTldyInfoDAO;

    @Resource
    SetlTldyExpertAuditMapper setlTldyExpertAuditMapper;


    @Override
    public ApiResult<List<SetlTldyInfoDTO>> getDipTldyInfoList(SetlTldyInfoQueyDTO setlTldyInfoDTO) throws Exception {
        List<SetlTldyInfoDTO> setlTldyInfoDTOS = dipTldyInfoDAO.selectTldyInfo(setlTldyInfoDTO);
        for (SetlTldyInfoDTO item : setlTldyInfoDTOS) {
            genAuditStr(item);
        }
        return ApiResult.success(setlTldyInfoDTOS);
    }

    @Override
    public void exportDipTldyInfo(SetlTldyInfoQueyDTO queryDto, HttpServletResponse response) throws Exception {
        List<SetlTldyExportDTO> list = queryExportTldyInfo(queryDto);
        for (SetlTldyExportDTO setlTldyExportDTO : list) {
            genExportAuditInfo(setlTldyExportDTO);
            genExportPropertiesName(setlTldyExportDTO);
        }
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");// 设置字符编码
        String fileName = URLEncoder.encode("特例单议审核列表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); // 设置响应头
        EasyExcel.write(response.getOutputStream(), SetlTldyExportDTO.class)
                .sheet("特例单议审核列表")
                .registerWriteHandler(HeadContentCellStyle.myHorizontalCellStyleStrategy())
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                .doWrite(list);
    }

    @Override
    public List<SetlTldyExportDTO> queryExportTldyInfo(SetlTldyInfoQueyDTO queryDto) throws Exception {

        if (Objects.isNull(queryDto)) {
            throw new CustomerException("请求参数不能为空");
        }
        if(queryDto.getStartTime() == null || queryDto.getEndTime() == null){
            throw new CustomerException("申请时间不可为空");
        }
        List<SetlTldyExportDTO> list = dipTldyInfoDAO.queryExportTldyInfo(queryDto);
        for (SetlTldyExportDTO setlTldyExportDTO : list) {
            genExportAuditInfo(setlTldyExportDTO);
            genExportPropertiesName(setlTldyExportDTO);
        }
        return list;
    }

    @Override
    public PageInfo<SetlTldyExportDTO2> queryExportTldyInfoNew(SetlTldyInfoQueyDTO queryDto) throws Exception {
        PageHelper.startPage(queryDto.getPageNum(),queryDto.getPageSize());
        List<SetlTldyExportDTO2> list = dipTldyInfoDAO.queryExportTldyInfoNew(queryDto);

        if (!CollectionUtils.isEmpty(list)) {
            List<String> tldyIds = list.stream().map(SetlTldyExportDTO2::getTldyId).collect(Collectors.toList());
            List<SetlTldyExpertAuditDTO> auditList = setlTldyExpertAuditMapper.selectByTldyIdList(tldyIds);
            setAuditInfo(list, auditList);
        }
        return new PageInfo<>(list);
    }

    private void setAuditInfo(List<SetlTldyExportDTO2> list, List<SetlTldyExpertAuditDTO> auditList) {
        for (SetlTldyExportDTO2 setlTldyExportDTO : list) {
            List<SetlTldyExpertAuditDTO> collect = auditList.stream()
                    .filter(item -> item.getTldyId().equals(setlTldyExportDTO.getTldyId()))
                    .collect(Collectors.toList());

            List<TldyAuditInfo> auditInfoList = new ArrayList<>();
            collect.forEach(item -> {
                TldyAuditInfo tldyAuditInfo = new TldyAuditInfo();
                BeanUtils.copyProperties(item, tldyAuditInfo);
                tldyAuditInfo.setAuditChkTime(item.getCheckTime());
                auditInfoList.add(tldyAuditInfo);

            });
            genExportAuditInfoHandle(auditInfoList, setlTldyExportDTO);
            genExportPropertiesName2(setlTldyExportDTO);
        }

    }

    private void genExportAuditInfoHandle(List<TldyAuditInfo> list, SetlTldyExportDTO2 item) {
        if (org.springframework.util.CollectionUtils.isEmpty(list)) {
            return;
        }
        List<TldyAuditInfo> chkAuditList = list.stream()
                .filter(auditInfo -> "1".equals(auditInfo.getStatus()))
                .collect(Collectors.toList());

        List<TldyAuditInfo> reChkAuditList = list.stream().filter(auditInfo -> "2".equals(auditInfo.getStatus()))
                .collect(Collectors.toList());

        if (!org.springframework.util.CollectionUtils.isEmpty(chkAuditList)) {
            chkAuditList.sort(Comparator.nullsFirst(Comparator.comparing(TldyAuditInfo::getAuditChkTime,Comparator.nullsFirst(Date::compareTo))));

            item.setExpertAName(chkAuditList.get(0).getDrName());
            item.setExpertAFixmedinsName(chkAuditList.get(0).getFixmedinsName());
            item.setExpertACheckStatus(TldyAuditEmum.getMsgByCode(chkAuditList.get(0).getChkStatus()));
            item.setExpertACheckRea(chkAuditList.get(0).getChkRea());

            item.setExpertBName(chkAuditList.get(1).getDrName());
            item.setExpertBFixmedinsName(chkAuditList.get(1).getFixmedinsName());
            item.setExpertBCheckStatus(TldyAuditEmum.getMsgByCode(chkAuditList.get(1).getChkStatus()));
            item.setExpertBCheckRea(chkAuditList.get(1).getChkRea());

            item.setExpertCName(chkAuditList.get(2).getDrName());
            item.setExpertCFixmedinsName(chkAuditList.get(2).getFixmedinsName());
            item.setExpertCCheckStatus(TldyAuditEmum.getMsgByCode(chkAuditList.get(2).getChkStatus()));
            item.setExpertCCheckRea(chkAuditList.get(2).getChkRea());
        }
        if (!org.springframework.util.CollectionUtils.isEmpty(reChkAuditList)) {
            reChkAuditList.sort(Comparator.nullsFirst(Comparator.comparing(TldyAuditInfo::getAuditChkTime,Comparator.nullsFirst(Date::compareTo))));

            item.setRecheckExpertAName(reChkAuditList.get(0).getDrName());
            item.setRecheckExpertAFixmedinsName(reChkAuditList.get(0).getFixmedinsName());
            item.setExpertARecheckStatus(TldyAuditEmum.getMsgByCode(reChkAuditList.get(0).getChkStatus()));
            item.setExpertARecheckRea(reChkAuditList.get(0).getChkRea());

            item.setRecheckExpertBName(reChkAuditList.get(1).getDrName());
            item.setRecheckExpertBFixmedinsName(reChkAuditList.get(1).getFixmedinsName());
            item.setExpertBRecheckStatus(TldyAuditEmum.getMsgByCode(reChkAuditList.get(1).getChkStatus()));
            item.setExpertBRecheckRea(reChkAuditList.get(1).getChkRea());
        } else {
            item.setRecheckOverTime(null);
        }

    }

    private void genExportPropertiesName2(SetlTldyExportDTO2 item) {

        //特病单议节点、审核状态
        if (!StringUtils.isEmpty(item.getStatus())) {
            String statusName = TldyStepEnum.getMsgByCode(item.getStatus());
            item.setStatusName(statusName);

            String auditStatus = "";
            if (TldyStepEnum.TLDY_STEP_1.getCode().equals(item.getStatus())) {
                auditStatus = TldyAuditEmum.getMsgByCode(item.getCheckStatus());

            } else if (TldyStepEnum.TLDY_STEP_2.getCode().equals(item.getStatus())) {
                auditStatus = TldyAuditEmum.getMsgByCode(item.getRecheckStatus());
            } else if (TldyStepEnum.TLDY_STEP_3.getCode().equals(item.getStatus())) {
                auditStatus = TldyAuditEmum.getMsgByCode(item.getRecheckStatus());
            } else {
                auditStatus = TldyAuditEmum.TLDY_AUDIT_0.getMsg();
            }
            item.setAuditStatus(auditStatus);
        }

        //特病单议申请原因
        if (!StringUtils.isEmpty(item.getApplyExitRea())) {
            String msgByCode = ApplyExitReaEnum.getMsgByCode(item.getApplyExitRea());
            String applyExitReaName = "";
            if (ApplyExitReaEnum.APPLY_EXIT_REA_1.getCode().equals(item.getApplyExitRea())) {
                assert msgByCode != null;
                applyExitReaName = String.format(msgByCode, item.getDaysOverstep()).toString();
            }else if (ApplyExitReaEnum.APPLY_EXIT_REA_2.getCode().equals(item.getApplyExitRea())) {
                assert msgByCode != null;
                applyExitReaName = String.format(msgByCode, item.getCostOverstep()).toString();
            } else {
                applyExitReaName = msgByCode;
            }
            item.setApplyExitReaName(applyExitReaName);
        }

        //学科名称
        if (!StringUtils.isEmpty(item.getDeptMajor())) {
            item.setDeptMajorName(DeptMajorEnum.getMsgByCode(item.getDeptMajor()));
        }
    }




    private void genExportPropertiesName(SetlTldyExportDTO item) {

        //特病单议节点、审核状态
        if (!StringUtils.isEmpty(item.getStatus())) {
            String statusName = TldyStepEnum.getMsgByCode(item.getStatus());
            item.setStatusName(statusName);

            String auditStatus = "";
            if (TldyStepEnum.TLDY_STEP_1.getCode().equals(item.getStatus())) {
                auditStatus = TldyAuditEmum.getMsgByCode(item.getCheckStatus());

            } else if (TldyStepEnum.TLDY_STEP_2.getCode().equals(item.getStatus())) {
                auditStatus = TldyAuditEmum.getMsgByCode(item.getRecheckStatus());
            } else if (TldyStepEnum.TLDY_STEP_3.getCode().equals(item.getStatus())) {
                auditStatus = TldyAuditEmum.getMsgByCode(item.getRecheckStatus());
            } else {
                auditStatus = TldyAuditEmum.TLDY_AUDIT_0.getMsg();
            }
            item.setAuditStatus(auditStatus);
        }

        //特病单议申请原因
        if (!StringUtils.isEmpty(item.getApplyExitRea())) {
            String msgByCode = ApplyExitReaEnum.getMsgByCode(item.getApplyExitRea());
            String applyExitReaName = "";
            if (ApplyExitReaEnum.APPLY_EXIT_REA_1.getCode().equals(item.getApplyExitRea())) {
                assert msgByCode != null;
                applyExitReaName = String.format(msgByCode, item.getDaysOverstep()).toString();
            }else if (ApplyExitReaEnum.APPLY_EXIT_REA_2.getCode().equals(item.getApplyExitRea())) {
                assert msgByCode != null;
                applyExitReaName = String.format(msgByCode, item.getCostOverstep()).toString();
            } else {
                applyExitReaName = msgByCode;
            }
            item.setApplyExitReaName(applyExitReaName);
        }

        //学科名称
        if (!StringUtils.isEmpty(item.getDeptMajor())) {
            item.setDeptMajorName(DeptMajorEnum.getMsgByCode(item.getDeptMajor()));
        }
    }

    private void genAuditStr(SetlTldyInfoDTO item) {
        String auditStr = item.getAuditStr();
        if (StringUtils.isEmpty(auditStr)) {
            return;
        }

        List<TldyAuditInfo> list = JSONObject.parseArray(auditStr, TldyAuditInfo.class);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<TldyAuditInfo> chkAuditList = list.stream()
                .filter(auditInfo -> "1".equals(auditInfo.getStatus()))
//                .sorted(Comparator.comparing(obj -> obj.getAuditChkTime() == null, Boolean::compareTo))
                .collect(Collectors.toList());

        List<TldyAuditInfo> reChkAuditList = list.stream().filter(auditInfo -> "2".equals(auditInfo.getStatus()))
//                .sorted(Comparator.comparing(obj -> obj.getAuditChkTime() == null, Boolean::compareTo))
                .collect(Collectors.toList());



        if (!CollectionUtils.isEmpty(chkAuditList)) {
            chkAuditList.sort(Comparator.nullsFirst(Comparator.comparing(TldyAuditInfo::getAuditChkTime,Comparator.nullsFirst(Date::compareTo))));
            item.setExpertACheckStatus(chkAuditList.get(0).getChkStatus());
            item.setExpertACheckRea(chkAuditList.get(0).getChkRea());

            item.setExpertBCheckStatus(chkAuditList.get(1).getChkStatus());
            item.setExpertBCheckRea(chkAuditList.get(1).getChkRea());

            item.setExpertCCheckStatus(chkAuditList.get(2).getChkStatus());
            item.setExpertCCheckRea(chkAuditList.get(2).getChkRea());
        }
        if (!CollectionUtils.isEmpty(reChkAuditList)) {
            reChkAuditList.sort(Comparator.nullsFirst(Comparator.comparing(TldyAuditInfo::getAuditChkTime,Comparator.nullsFirst(Date::compareTo))));
            item.setExpertARecheckStatus(reChkAuditList.get(0).getChkStatus());
            item.setExpertARecheckRea(reChkAuditList.get(0).getChkRea());

            item.setExpertBRecheckStatus(reChkAuditList.get(1).getChkStatus());
            item.setExpertBRecheckRea(reChkAuditList.get(1).getChkRea());

        }
    }

    private void genExportAuditInfo(SetlTldyExportDTO item) {
        String exportAuditInfo = item.getExportAuditInfo();
        if (StringUtils.isEmpty(exportAuditInfo)) {
            return;
        }

        List<TldyAuditInfo> list = JSONObject.parseArray(exportAuditInfo, TldyAuditInfo.class);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<TldyAuditInfo> chkAuditList = list.stream()
                .filter(auditInfo -> "1".equals(auditInfo.getStatus()))
                .collect(Collectors.toList());

        List<TldyAuditInfo> reChkAuditList = list.stream().filter(auditInfo -> "2".equals(auditInfo.getStatus()))
                .collect(Collectors.toList());



        if (!CollectionUtils.isEmpty(chkAuditList)) {
            chkAuditList.sort(Comparator.nullsFirst(Comparator.comparing(TldyAuditInfo::getAuditChkTime,Comparator.nullsFirst(Date::compareTo))));

            item.setExpertACheckStatus(TldyAuditEmum.getMsgByCode(chkAuditList.get(0).getChkStatus()));
            item.setExpertACheckRea(chkAuditList.get(0).getChkRea());

            item.setExpertBCheckStatus(TldyAuditEmum.getMsgByCode(chkAuditList.get(1).getChkStatus()));
            item.setExpertBCheckRea(chkAuditList.get(1).getChkRea());

            item.setExpertCCheckStatus(TldyAuditEmum.getMsgByCode(chkAuditList.get(2).getChkStatus()));
            item.setExpertCCheckRea(chkAuditList.get(2).getChkRea());
        }
        if (!CollectionUtils.isEmpty(reChkAuditList)) {
            reChkAuditList.sort(Comparator.nullsFirst(Comparator.comparing(TldyAuditInfo::getAuditChkTime,Comparator.nullsFirst(Date::compareTo))));
            item.setExpertARecheckStatus(TldyAuditEmum.getMsgByCode(reChkAuditList.get(0).getChkStatus()));
            item.setExpertARecheckRea(reChkAuditList.get(0).getChkRea());

            item.setExpertBRecheckStatus(TldyAuditEmum.getMsgByCode(reChkAuditList.get(1).getChkStatus()));
            item.setExpertBRecheckRea(reChkAuditList.get(1).getChkRea());
        } else {
            item.setRecheckOverTime(null);
        }
    }

    public static void main(String[] args) {
        String str = "住院天数超过上年度该统筹区同级别定点医疗机构该病组(DRG)/病种(DIP)平均住院天数%s倍(含)的";

        String applyExitReaName = String.format(str, "5");
        System.out.println(applyExitReaName);
    }
}
